/*
*********************************************************************************************************
*                                       LK_WDR software
*
*                             (c) Copyright 2015; DL-Laike
*
*                   All rights reserved.  Protected by international copyright laws.
*                   Knowledge of the source code may not be used to write a similar
*                   product.  This file may only be used in accordance with a license
*                   and should not be redistributed in any way.
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*
*                                       	the MAIN file
*                             ST Microelectronics STM32 with the STM32F407IGT6
*
* Filename      : main.c
* Version       : V1.0
* Programmer(s) : ZhangYu
*********************************************************************************************************
*/

#include "includes.h"


/********************************************************************************************************
											private function declare
********************************************************************************************************/

static void AppTaskCreate (void);
static void AppTaskObject (void);
static void AppTaskInitUserData(void);
static void readConfigParams( void );
static void setDefaultUserCustomerParams( void );

/********************************************************************************************************
											global variable define
********************************************************************************************************/

__IO uint32_t 			localtime;			//local ticket count -> ETH APP and other task

//OS resource
xSemaphoreHandle xSem_UserData 	= NULL;		//user data access locker for extend SRAM
xSemaphoreHandle xSem_E2PROM 	= NULL;		//user data access locker for extend SRAM
xSemaphoreHandle xSem_TRDP		= NULL;		//signal semaphore for High speed timer
xQueueHandle xQue_CAN2 			= NULL;		//message queue for the CAN2 PORT
xQueueHandle xQue_CAN1 			= NULL;		//message queue for the CAN1 PORT
xQueueHandle xQue_W5500			= NULL;		//message queue for the Ethernet frames
xQueueHandle xQue_E2PROM		= NULL;		//message queue for the SD Card
xQueueHandle xQue_RTC			= NULL;		//message queue for the RTC


//user global data
SYS_USER_REGS				gSysUserRegs;		//User Data structure
__IO SYS_USER_REGS 	* const p_gSysUserRegs = &gSysUserRegs;	//pointer to User Data

/*******************************************************************************
* Function Name  : vApplicationTickHook
* Description    : This function is OS's tick hook function
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void vApplicationTickHook( void )
{
	localtime++;				//used to calculate local times
}


/*******************************************************************************
* Function Name  : main
* Description    : the main function
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
int main(void)
{
	/*configure the HW before OS start*/
	bsp_Init();
	
	/*wait for the HW to be stable*/
	BSP_DelayMS(5);

	/*configure GPIOs to be the default state*/
	BSP_GPIO_SetNormalState();

	/*wait for the HW to be reset OK*/
	BSP_DelayMS(5);
	
	/* TASK Create */
	AppTaskCreate();

	/* OS Resource Create*/
	AppTaskObject();

    /* begin OS */
    vTaskStartScheduler();

    /* 
	   If all is well we will never reach here as the scheduler will now be
	   running.  If we do reach here then it is likely that there was insufficient
	   heap available for the idle task to be created. 
		*/
    while (1) {
    } 
}

/*******************************************************************************
* Function Name  : AppTaskInitUserData
* Description    : this function set user data to default value
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
static void AppTaskInitUserData(void)
{
	//initial global user data
	union uTemp{
		uint32_t CPU_Sn[3];
		uint8_t	 CRC16_buf[sizeof(uint32_t)*3];
	}uTemp;

	EthInitStatus = 0;
	EthLinkStatus = 0;

	memset(&gSysUserRegs,0,sizeof(gSysUserRegs));

	BSP_GetUID(&uTemp.CPU_Sn[0], &uTemp.CPU_Sn[1], &uTemp.CPU_Sn[2]);

	p_gSysUserRegs->UIDValue = BSP_CRC16_CalcCRC(uTemp.CRC16_buf, (sizeof(uint32_t)*3));

	p_gSysUserRegs->CPU_Sn[0] = uTemp.CPU_Sn[0];
	p_gSysUserRegs->CPU_Sn[1] = uTemp.CPU_Sn[1];
	p_gSysUserRegs->CPU_Sn[2] = uTemp.CPU_Sn[2];
	/*read data from EEPROM*/
	readConfigParams();
}

/*******************************************************************************
* Function Name  : TASK_InitWork
* Description    : create all the Tasks and fed the two watch Dog
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void TASK_InitWork( void *pvParameters )
{
	/*configure User Data*/
	AppTaskInitUserData();
	//--------------Configure HW Common AF Resource (It's better after OS is started)----------------------
	//--------------communication AF Resources will be configured in the tasks-----------------------------
	bsp_Init_AfterOS();

	//-------------Create TASK Start-------------------------
	    /* Create CAN Task for parameter */
    xTaskCreate(    TASK_CAN,     			/* Pointer to the function that implements the task.              */
                    "CAN",   				/* Text name for the task.  This is to facilitate debugging only. */
					osStackSizeNormal,      /* Stack depth in words.                                          */
                    NULL,       			/* We are not using the task parameter.                           */
					osPriorityAboveNormal,  		/* This task will run at priority 5.                      */
                    NULL );     			/* We are not using the task handle.*/
	
//    xTaskCreate(    TASK_TRDP,     			/* Pointer to the function that implements the task.              */
//                    "TRDP",   				/* Text name for the task.  This is to facilitate debugging only. */
//                    osStackSizeNormal,      /* Stack depth in words.                                          */
//                    NULL,       			/* We are not using the task parameter.                           */
//										osPriorityNormal,  		/* This task will run at priority 5.                      */
//                    NULL );     			/* We are not using the task handle.*/

//    xTaskCreate(    TASK_PROC,     			/* Pointer to the function that implements the task.              */
//                    "PROC",   				/* Text name for the task.  This is to facilitate debugging only. */
//										osStackSizeLarge,      	/* Stack depth in words.                                          */
//                    NULL,       			/* We are not using the task parameter.                           */
//										osPriorityBelowNormal,  /* This task will run at priority 5.                        	  */
//                    NULL );     			/* We are not using the task handle.*/

    xTaskCreate(    TASK_OutPut,			/* Pointer to the function that implements the task.              */
                    "OutPut",   			/* Text name for the task.  This is to facilitate debugging only. */
										osStackSizeNormal,      /* Stack depth in words.                                          */
                    NULL,       			/* We are not using the task parameter.                           */
										osPriorityNormal,  		/* This task will run at priority 5.                        	  */
                    NULL );     			/* We are not using the task handle.*/

	//we should open it when the real board
	if(GPIO_ReadInputDataBit(HW_TYPE_PORT, HW_TYPE_PIN) == HW_TYPE_NEW){
#if USE_SD_RTC_Enable == 1
		/* Create RTC Task. */
		xTaskCreate(  TASK_RTC,     					/* Pointer to the function that implements the task.              */
									"RTC",   								/* Text name for the task.  This is to facilitate debugging only. */
									osStackSizeNormal,  		/* Stack depth in words.                                          */
									NULL,       						/* We are not using the task parameter.                           */
									osPriorityLow,  				/* This task will run at priority 5.                        	  	*/
									NULL );     						/* We are not using the task handle.*/
#endif

		/* Create MRAM Task. */
		xTaskCreate(  TASK_E2PROM,     				/* Pointer to the function that implements the task.              */
									"E2PROM",   						/* Text name for the task.  This is to facilitate debugging only. */
									osStackSizeNormal,      /* Stack depth in words.                                          */
									NULL,       						/* We are not using the task parameter.                           */
									osPriorityRealtime,  		/* This task will run at priority 5.                        	  	*/
									NULL );     						/* We are not using the task handle.*/
	}

	vTaskDelay(100);

//#if USE_W5500_Enable == 1
//	/* Create RS485 Task. */
//    xTaskCreate(    TASK_W5500,     		/* Pointer to the function that implements the task.              */
//                    "W5500",   				/* Text name for the task.  This is to facilitate debugging only. */
//					osStackSizeLarge,       /* Stack depth in words.                                           */
//                    NULL,       			/* We are not using the task parameter.                           */
//					osPriorityAboveNormal,  /* This task will run at priority 5.                        	  */
//                    NULL );     			/* We are not using the task handle.*/
//#endif

	/* Create ETH Task. */
   xTaskCreate(    TASK_BRIDGE,     			/* Pointer to the function that implements the task.              */
                   "BRIDGE",   				/* Text name for the task.  This is to facilitate debugging only. */
                   osStackSizeNormal,      /* Stack depth in words.                                          */
                   NULL,       			/* We are not using the task parameter.                           */
                   osPriorityHigh,  		/* This task will run at priority 5.                        	  */
                   NULL );     			/* We are not using the task handle.*/


    //TASK_InitWork Run for the watch Dog-----------------
    while(1)
    {
    	//feed internal watch Dog
    	BSP_IWDG_Feed();
    	//we run every 500ms
    	vTaskDelay(200);
    }
}

/*******************************************************************************
* Function Name  : AppTaskCreate
* Description    : create InitWork Task
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
static void AppTaskCreate (void)
{
	/* Create InitWork Task. */
    xTaskCreate(    TASK_InitWork,     		/* Pointer to the function that implements the task.              */
                    "INIT",   				/* Text name for the task.  This is to facilitate debugging only. */
                    osStackSizeSmall,       /* Stack depth in words.                                          */
                    NULL,       			/* We are not using the task parameter.                           */
                    osPriorityLow,       	/* This task will run at priority 1.                              */
                    NULL );     			/* We are not using the task handle.                              */

}

/*******************************************************************************
* Function Name  : AppTaskObject
* Description    : create TASK's resource
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
static void AppTaskObject (void)
{
	vSemaphoreCreateBinary( xSem_UserData );				//global user data locker
	vSemaphoreCreateBinary( xSem_TRDP );					//global user data locker
	vSemaphoreCreateBinary( xSem_E2PROM );					//global CAN1 Access locker
	xQue_CAN2	= xQueueCreate(64,sizeof(CanRxMsg));		//message Queue for FI TASK

	/*
	 * suppose we use 100ms to record all the data to Disk, 125Kbps Can can send 156 frames
	 * so we set queue length = 160 to make sure we can hold all the Can Data in the time
	 * we record all the data
	 * */
	xQue_CAN1	= xQueueCreate(64,sizeof(CanRxMsg));		//message Queue for CAN TASK
	xQue_W5500  = xQueueCreate(4,sizeof(ETH_MSG));			//message Queue for W5500 TASK
	xQue_E2PROM  = xQueueCreate(8,sizeof(E2PROM_MSG));		//message Queue for SD Card
	xQue_RTC	 = xQueueCreate(2,sizeof(TTime));		//message Queue for RTC TASK

	if((xSem_UserData == NULL) ||
		(xSem_TRDP == NULL) 	||
		(xSem_E2PROM == NULL) ||
		(xQue_W5500 == NULL) 	||
		(xQue_E2PROM == NULL) ||
		(xQue_RTC == NULL) 		||
		(xQue_CAN2 == NULL)		||
		(xQue_CAN1 == NULL)){
		//set LESs to display errCode
		BSP_GPIO_SetLedAllOn();
		while(1);
	}
}

/*******************************************************************************
* Function Name  : AppTaskObject
* Description    : create TASK's resource
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
static void readConfigParams( void )
{
	setDefaultUserCustomerParams();
}

/*******************************************************************************
* Function Name  : AppTaskObject
* Description    : create TASK's resource
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
static void setDefaultUserCustomerParams( void )
{
	//BSP_readFlash(( FLASH_USER_START_ADDR + 4), (uint8_t *)&dev_pos_state, 4);

		
	//config MAC
	p_gSysUserRegs->MR_Para.MAC_ADDR[0]		= MAC_ADDR0;
	p_gSysUserRegs->MR_Para.MAC_ADDR[1]		= MAC_ADDR1;
	p_gSysUserRegs->MR_Para.MAC_ADDR[2]		= MAC_ADDR2;
	p_gSysUserRegs->MR_Para.MAC_ADDR[3]		= MAC_ADDR3;
	//auto set mac address last two bytes
	p_gSysUserRegs->MR_Para.MAC_ADDR[4]		=(p_gSysUserRegs->UIDValue>>8);
	p_gSysUserRegs->MR_Para.MAC_ADDR[5]		=(p_gSysUserRegs->UIDValue);

	//config local IP address
	// p_gSysUserRegs->MR_Para.IP_ADDR[0]		= IP_ADDR0;
	// p_gSysUserRegs->MR_Para.IP_ADDR[1]		= IP_ADDR1;
	// p_gSysUserRegs->MR_Para.IP_ADDR[2]		= IP_ADDR2;
	// p_gSysUserRegs->MR_Para.IP_ADDR[3]		= IP_ADDR3;
	p_gSysUserRegs->MR_Para.IP_ADDR[0]		= 10;
	p_gSysUserRegs->MR_Para.IP_ADDR[1]		= 0;
	p_gSysUserRegs->MR_Para.IP_ADDR[2]		= 8;
	p_gSysUserRegs->MR_Para.IP_ADDR[3]		= 27;


	/*Net Mask Address*/
	p_gSysUserRegs->MR_Para.NETMASK_ADDR[0]		= NETMASK_ADDR0;
	p_gSysUserRegs->MR_Para.NETMASK_ADDR[1]		= NETMASK_ADDR1;
	p_gSysUserRegs->MR_Para.NETMASK_ADDR[2]		= NETMASK_ADDR2;
	p_gSysUserRegs->MR_Para.NETMASK_ADDR[3]		= NETMASK_ADDR3;
	/*GW Address*/
	p_gSysUserRegs->MR_Para.GW_ADDR[0]		= GW_ADDR0;
	p_gSysUserRegs->MR_Para.GW_ADDR[1]		= GW_ADDR1;
	p_gSysUserRegs->MR_Para.GW_ADDR[2]		= GW_ADDR2;
	p_gSysUserRegs->MR_Para.GW_ADDR[3]		= GW_ADDR3;


	p_gSysUserRegs->MR_Para.MAC_ADDR_RDNC[0]		= MAC_ADDR0_RDNC;
	p_gSysUserRegs->MR_Para.MAC_ADDR_RDNC[1]		= MAC_ADDR1_RDNC;
	p_gSysUserRegs->MR_Para.MAC_ADDR_RDNC[2]		= MAC_ADDR2_RDNC;
	p_gSysUserRegs->MR_Para.MAC_ADDR_RDNC[3]		= MAC_ADDR3_RDNC;
	p_gSysUserRegs->MR_Para.MAC_ADDR_RDNC[4]		= (p_gSysUserRegs->UIDValue>>8);
	p_gSysUserRegs->MR_Para.MAC_ADDR_RDNC[5]		= (p_gSysUserRegs->UIDValue);

	p_gSysUserRegs->MR_Para.IP_ADDR_RDNC[0]		= IP_ADDR0_RDNC;
	p_gSysUserRegs->MR_Para.IP_ADDR_RDNC[1]		= IP_ADDR1_RDNC;
	p_gSysUserRegs->MR_Para.IP_ADDR_RDNC[2]		= IP_ADDR2_RDNC;
	p_gSysUserRegs->MR_Para.IP_ADDR_RDNC[3]		= IP_ADDR3_RDNC;


	p_gSysUserRegs->MR_Para.NETMASK_ADDR_RDNC[0]		= NETMASK_ADDR0_RDNC;
	p_gSysUserRegs->MR_Para.NETMASK_ADDR_RDNC[1]		= NETMASK_ADDR1_RDNC;
	p_gSysUserRegs->MR_Para.NETMASK_ADDR_RDNC[2]		= NETMASK_ADDR2_RDNC;
	p_gSysUserRegs->MR_Para.NETMASK_ADDR_RDNC[3]		= NETMASK_ADDR3_RDNC;

	p_gSysUserRegs->MR_Para.GW_ADDR_RDNC[0]		= GW_ADDR0_RDNC;
	p_gSysUserRegs->MR_Para.GW_ADDR_RDNC[1]		= GW_ADDR1_RDNC;
	p_gSysUserRegs->MR_Para.GW_ADDR_RDNC[2]		= GW_ADDR2_RDNC;
	p_gSysUserRegs->MR_Para.GW_ADDR_RDNC[3]		= GW_ADDR3_RDNC;

	/*CAN BAND RATE*/
	p_gSysUserRegs->MR_Para.CAN1_Bandrate = CAN1_COM_BANDRATE;
	/*RS485 bandrate*/
	p_gSysUserRegs->MR_Para.CAN2_Bandrate = CAN2_COM_BANDRATE;
}


/***************************** DaLian Like (END OF FILE) *********************************/

